﻿using HCMS.CommonDtos;
using HCMS.Dtos.OAuth2;
using HCMS.Entities.OAuth2;
using HCMS.IRepositories.OAuth2;
using HCMS.IServices.OAuth2;
using HCMS.Repositories.OAuth2;
using HCMS.Utils;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;

namespace HCMS.Services.OAuth2
{
    /// <summary>
    /// OAuth 2.0 AccessToken 应用服务
    /// </summary>
    public class OAuth2AccessTokenAppService : CommonAppService<OAuth2DbContext, OAuth2AccessToken>, IOAuth2AccessTokenAppService
    {
        private readonly IRepository<OAuth2AccessToken> baseOAuth2AccessTokenRepository;
        private readonly IOAuth2AccessTokenRepository oauth2AccessTokenRepository;
        private readonly IOAuth2AppRepository oauth2AppRepository;

        public OAuth2AccessTokenAppService(
            IRepository<OAuth2AccessToken> baseOAuth2AccessTokenRepository,
            IOAuth2AccessTokenRepository oauth2AccessTokenRepository,
            IOAuth2AppRepository oauth2AppRepository
            ) : base(baseOAuth2AccessTokenRepository)
        {
            this.baseOAuth2AccessTokenRepository = baseOAuth2AccessTokenRepository;
            this.oauth2AccessTokenRepository = oauth2AccessTokenRepository;
            this.oauth2AppRepository = oauth2AppRepository;
        }

        /// <summary>
        /// 管理 列表
        /// </summary>
        /// <param name="searchArgs">搜索 参数</param>
        /// <param name="pager">分页 参数</param>
        /// <returns></returns>
        public async Task<ListPagerDto<object>> ManageList(SearchArgsDto searchArgs, PagerArgsDto pager)
        {
            var oauth2AccessToken = await oauth2AccessTokenRepository.ManageList(searchArgs, pager);

            var result = new ListPagerDto<object>();
            result.PagerInfo = oauth2AccessToken.PagerInfo;

            var data = new List<object>();
            foreach (var item in oauth2AccessToken.Data)
            {
                data.Add(new
                {
                    id = item.Id,
                    createTime = item.CreateTime,
                    token = item.Token,
                    expirationTime = item.CreateTime.AddSeconds(item.ExpiresIn)
                });
            }

            result.Data = data;

            return result;
        }

        /// <summary>
        /// 根据应用 Id 获取 AccessToken
        /// </summary>
        /// <param name="appId">应用 Id</param>
        /// <returns></returns>
        public async Task<AppTokenDto> TokenByAppId(int appId)
        {
            var token = RandomUtil.GetRandomString("", 125);
            var expiresIn = 30 * 60 * 60 * 24;  // 凭证有效期。单位：秒。 默认：30 天

            var tokenEntity = await BaseInsertAsync(new OAuth2AccessToken()
            {
                CreateTime = DateTime.Now,
                AppId = appId,
                Token = token,
                ExpiresIn = expiresIn,
            });

            var result = new AppTokenDto();
            if (tokenEntity != null)
            {
                result.AccessToken = tokenEntity.Token;
                result.ExpiresIn = tokenEntity.ExpiresIn;
            }

            return result;
        }

        /// <summary>
        /// AccessToken 有效性验证
        /// </summary>
        /// <param name="token">token 信息</param>
        /// <returns></returns>
        public async Task<bool> TokenValidation(string token)
        {
            if (string.IsNullOrWhiteSpace(token))
            {
                return false;
            }

            var tokenEntity = await BaseFirstOrDefaultAsync(t => t.Token == token);
            if (tokenEntity == null)
            {
                return false;
            }
            if (tokenEntity.CreateTime.AddSeconds(tokenEntity.ExpiresIn) < DateTime.Now)
            {
                return false;
            }
            else
            {
                var oauthApp = await oauth2AppRepository.FirstOrDefaultAsync(t => t.Id == tokenEntity.AppId);
                if (oauthApp == null || oauthApp.Status != 0)
                {
                    return false;
                }

                return true;
            }
        }
    }
}
